package com.bbzn.device.client.service.impl;

import com.bbzn.device.client.constant.DeviceConstant;
import com.bbzn.device.client.dataobject.*;
import com.bbzn.device.client.dto.ct.data.TemplateDeviceDTO;
import com.bbzn.device.client.dto.device.*;
import com.bbzn.device.client.exception.DefinitException;
import com.bbzn.device.client.service.*;
import com.bbzn.device.client.utils.PageInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.bbzn.device.client.dao.device.DeviceMapper;

@Service
public class DeviceServiceImpl implements DeviceService {

//    //定义一个容量为10000的阻塞队列，BlockingQueue线程安全可以多个生产者同时put
//    private BlockingQueue<Device> dataQueue = new LinkedBlockingQueue<Device>(10000);
//
//    private Device device = new Device();
//
//    //put任务的方法，供生产者调用
//    @Override
//    public void updateQueenByImei(Device job) {
//        try {
//            dataQueue.put(job);
//        } catch (InterruptedException e) {
//            Thread.currentThread().interrupt();
//        }
//    }

//    @PostConstruct
//    @Override
//    public void init() {
//        Thread thread = new Thread(() -> {
//            while (Boolean.TRUE) {
//                Device poll = null;
//                boolean pollTimeOut = false;
//                long startTime;
//                long endTime;
//                try {
//                    // poll时设置超时时间为6秒
//                    poll = dataQueue.poll(6, TimeUnit.SECONDS);
//                } catch (InterruptedException e) {
//                    Thread.currentThread().interrupt();
//                }
//                if (null != poll) {
//                    // poll到任务添加到List中
//                    list.add(poll);
//                } else {
//                    // poll超时，设置超时标志位
//                    pollTimeOut = true;
//                }
//
//                // 如果任务List等于5000或poll超时且List中还有任务就批量更新
//                if (list.size() == 300 ||
//                        (pollTimeOut && !CollectionUtils.isEmpty(list))) {
//                    startTime = System.currentTimeMillis();
//                    batchInsert(list);
//                    logger.info("启动批量【GPS轨迹上传】守护线程---Job任务批量更新{}条任务,耗时{}毫秒", list.size(),
//                            System.currentTimeMillis() - startTime);
//                    list.clear();
//                }
//            }
//        });

//        thread.setName("job-batchUpdate-deamon");
//        // 设置启动的线程为守护线程 直到jvm停了才停止
//        thread.setDaemon(true);
//        thread.start();
//    }

    @Resource
    private DeviceMapper deviceMapper;

    @Autowired
    private SystemParamByCacheService systemParamByCacheService;

    @Autowired
    private DeviceCategoryService deviceCategoryService;

    @Autowired
    private DeviceManagementService deviceManagementService;

    @Autowired
    private FenceService fenceService;
    @Autowired
    private FenceDeviceService fenceDeviceService;
    @Autowired
    private DeviceProcessService deviceProcessService;
    @Autowired
    private DeviceShareService deviceShareService;
    @Autowired
    private AlarmHisService alarmHisService;
    @Autowired
    private AlarmHisEnService alarmHisEnService;
    @Autowired
    private AqiHisService aqiHisService;
    @Autowired
    private BloodOxygenHisService bloodOxygenHisService;
    @Autowired
    private ElevationHisService elevationHisService;
    @Autowired
    private GpsHisService gpsHisService;
    @Autowired
    private GroupDeviceService groupDeviceService;
    @Autowired
    private HumidityHisService humidityHisService;
    @Autowired
    private LocusCoordinateService locusCoordinateService;
    @Autowired
    private OutsideTemperatureHisService outsideTemperatureHisService;
    @Autowired
    private PressureHisService pressureHisService;
    @Autowired
    private SosService sosService;
    @Autowired
    private TemperatureHisService temperatureHisService;

    @Override
    public int deleteByPrimaryKey(Long id) {
        return deviceMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(Device record) {
        return deviceMapper.insert(record);
    }

    @Override
    public int insertOrUpdate(Device record) {
        return deviceMapper.insertOrUpdate(record);
    }

    @Override
    public int insertOrUpdateSelective(Device record) {
        return deviceMapper.insertOrUpdateSelective(record);
    }

    @Override
    public int insertSelective(Device record) {
        return deviceMapper.insertSelective(record);
    }

    @Override
    public Device selectByPrimaryKey(Long id) {
        return deviceMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(Device record) {
        return deviceMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(Device record) {
        return deviceMapper.updateByPrimaryKey(record);
    }

    @Override
    public List<Device> findByAll(Device device) {
        return deviceMapper.findByAll(device);
    }

    @Override
    public List<String> findByAllImeis(Long userId) {
        return deviceMapper.findByAllImeis(userId);
    }

    @Override
    public TemplateDeviceDTO getInfoByImei(String imei) {
        return deviceMapper.getInfoByImei(imei);
    }

    @Override
    public int updateBatch(List<Device> list) {
        return deviceMapper.updateBatch(list);
    }

    @Override
    public int updateBatchSelective(List<Device> list) {
        return deviceMapper.updateBatchSelective(list);
    }

    @Override
    public int batchInsert(List<Device> list) {
        return deviceMapper.batchInsert(list);
    }

    @Override
    public int findCountByAll(DeviceDTO record) {
        return deviceMapper.findCountByAll(record);
    }

    @Override
    public int findDevCategoryByDeviceCount(DeviceDTO record) {
        return deviceMapper.findDevCategoryByDeviceCount(record);
    }

    @Override
    public int updateByImeiSelective(Device record) {
        return deviceMapper.updateByImeiSelective(record);
    }

    @Override
    public PageInfo<Device> findPageByAll(DeviceDTO record) {
        PageInfo<Device> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(record.getPageNum());
        pageInfo.setPageSize(record.getPageSize());
        pageInfo.setResultList(deviceMapper.findPageByAll(record));
        int count = deviceMapper.findCountByAll(record);
        pageInfo.setTotalRecord(count);
        return pageInfo;
    }

    @Override
    public List<DeviceInfoDTO> findIndexAll(DeviceDTO record) {
        return deviceMapper.findIndexAll(record);
    }

    @Override
    public int getMonthOnlineCount(DeviceDTO record) {
        return deviceMapper.getMonthOnlineCount(record);
    }

    @Override
    public List<Device> selectProcessBySelective(DeviceDTO record) {
        return deviceMapper.selectProcessBySelective(record);
    }

    @Override
    public List<Long> getOperatorIdsBySelective(DeviceDTO record) {
        return deviceMapper.getOperatorIdsBySelective(record);
    }

    @Override
    public List<Device> selectByimeis(Set<String> imeis) {
        return deviceMapper.selectByimeis(imeis);
    }

    @Override
    public List<Device> selectByIds(List<Long> ids) {
        return deviceMapper.selectByIds(ids);
    }

    @Override
    public RateDTO getRateInfoByImei(String imei) {
        return deviceMapper.getRateInfoByImei(imei);
    }

    @Override
    public TempDTO getTempInfoByImei(String imei) {
        return deviceMapper.getTempInfoByImei(imei);
    }

    @Override
    public PressureDTO getPressureInfoByImei(String imei) {
        return deviceMapper.getPressureInfoByImei(imei);
    }

    @Override
    public BloodOxyDTO getBloodOxyInfoByImei(String imei) {
        return deviceMapper.getBloodOxyInfoByImei(imei);
    }

    @Override
    public VoltageDTO getVoltageInfoByImei(String imei) {
        return deviceMapper.getVoltageInfoByImei(imei);
    }

    @Override
    public HarmfulGasDTO getHarmfulGasInfoByImei(String imei) {
        return deviceMapper.getHarmfulGasInfoByImei(imei);
    }

    @Override
    public OutTemperatureDTO getTemperatureByImei(String imei) {
        return deviceMapper.getTemperatureByImei(imei);
    }

    @Override
    public ElevationDTO getElevationByImei(String imei) {
        return deviceMapper.getElevationByImei(imei);
    }

    @Override
    public SlotTypeDTO getSlotTypeByImei(String imei) {
        return deviceMapper.getSlotTypeByImei(imei);
    }

    @Override
    public GreetingDTO getGreetingInfoByImei(String imei) {
        return deviceMapper.getGreetingInfoByImei(imei);
    }

    @Override
    public SkuDTO selectSkuByImei(String imei) {
        return deviceMapper.selectSkuByImei(imei);
    }

    @Override
    public List<String> getUnUsedImei(List<Long> userIds, String imei, Long productId) {
        return deviceMapper.getUnUsedImei(userIds, imei, productId);
    }

    @Override
    public DeviceInfoDTO selectByImei(String imei) {
        return deviceMapper.selectByImei(imei);
    }

    @Override
    public Device selByImei(String imei) {
        return deviceMapper.selByImei(imei);
    }

    @Override
    public String getTopicByImei(String imei) {
        return deviceMapper.getTopicByImei(imei);
    }

    @Override
    public DevicePopupDTO selDevicePopup(String imei) {
        return deviceMapper.selDevicePopup(imei);
    }

    @Override
    public List<DeviceCountDTO> selectFireDeviceCount(List<Long> userIds) {
        return deviceMapper.selectFireDeviceCount(userIds);
    }

    @Override
    public List<FireIndexDTO> selectFireDevice(List<Long> userIds) {
        return deviceMapper.selectFireDevice(userIds);
    }

    @Override
    public PageInfo<Device> selectPageBySelective(DeviceDTO record) {
        PageInfo<Device> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(record.getPageNum());
        pageInfo.setPageSize(record.getPageSize());
        pageInfo.setResultList(deviceMapper.selectPageBySelective(record));
        int count = deviceMapper.selectCountBySelective(record);
        pageInfo.setTotalRecord(count);
        return pageInfo;
    }

    @Override
    public void bindCompany(Long userId, Long devId, Long receiveId, String userName, String language) throws Exception {
        SystemParam systemParam = null;
        Device dev = selectByPrimaryKey(devId);
        if (dev.getUsed() == 3) {
            systemParam = systemParamByCacheService.getValues(DeviceConstant.DEVICE_ENUM, DeviceConstant.DEVICE_IS_IN_USE_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }

        //先判断流程表是否存在该节点
        DeviceProcess dp = new DeviceProcess();
        dp.setOperatorId(userId);
        dp.setReceiveId(receiveId);
        dp.setImei(dev.getImei());
        dp.setUsed(2);
        List<DeviceProcess> deviceProcessList = deviceProcessService.findByAll(dp);
        if (CollectionUtils.isNotEmpty(deviceProcessList)) {
            systemParam = systemParamByCacheService.getValues(DeviceConstant.DEVICE_ENUM, DeviceConstant.DEVICE_FLOW_EXIST_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }

        Device device = new Device();
        device.setId(devId);
        //分配是变更“归属人”
        device.setUserId(receiveId);
        device.setUpdateTime(new Date());
        // 需要客户自己分配
        device.setUsed(2);
        updateByPrimaryKeySelective(device);

        //记录流程
        DeviceProcess deviceProcess = new DeviceProcess();
        //当前登录的用户
        deviceProcess.setOperatorId(userId);
        //接收的用户
        deviceProcess.setReceiveId(receiveId);
        deviceProcess.setImei(dev.getImei());
        deviceProcess.setUsed(2);
        deviceProcess.setCreateTime(new Date());
        deviceProcess.setCreatedBy(userName);
        deviceProcessService.insertSelective(deviceProcess);
    }

    @Override
    public void bingCompanies(Long userId, List<Long> devIds, Long receiveId, String userName, String language) throws Exception {
        SystemParam systemParam = null;
        List<Device> deviceList = selectByIds(devIds);
        //筛选- 筛选已绑定的卡
        List<Device> useList = deviceList.stream().filter(device -> (device.getUsed() == 3)).collect(Collectors.toList());
        //筛选- 筛选未绑定的卡
        List<Device> optList = deviceList.stream().filter(
                device -> !useList.stream().collect(Collectors.toList()).contains(device)
        ).collect(Collectors.toList());

        List<String> imeis = new ArrayList<>();
        deviceList.stream().forEach(dev -> {
            imeis.add(dev.getImei());
        });

        List<Device> devices = new ArrayList<>();
        List<DeviceProcess> deviceProcesses = new ArrayList<>();

        //先判断流程表是否存在该节点
        DeviceProcessDTO dpDTO = new DeviceProcessDTO();
        dpDTO.setOperatorId(userId);
        dpDTO.setReceiveId(receiveId);
        dpDTO.setImeis(imeis);
        dpDTO.setUsed(2);
        List<DeviceProcess> deviceProcessList = deviceProcessService.selectByimeis(dpDTO);
        if (CollectionUtils.isNotEmpty(deviceProcessList)) {
            systemParam = systemParamByCacheService.getValues(DeviceConstant.DEVICE_ENUM, DeviceConstant.DEVICE_FLOW_EXIST_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }

        optList.stream().forEach(dev -> {
            Device device = new Device();
            device.setId(dev.getId());
            //分配是变更“归属人”
            device.setUserId(receiveId);
            device.setUsed(2);
            device.setUpdateTime(new Date());
            devices.add(device);

            //记录流程
            DeviceProcess deviceProcess = new DeviceProcess();
            //当前登录的用户
            deviceProcess.setOperatorId(userId);
            //接收的用户
            deviceProcess.setReceiveId(receiveId);
            deviceProcess.setImei(dev.getImei());
            deviceProcess.setUsed(2);
            deviceProcess.setCreateTime(new Date());
            deviceProcess.setCreatedBy(userName);
            deviceProcesses.add(deviceProcess);
        });
        updateBatchSelective(devices);
        deviceProcessService.batchInsert(deviceProcesses);
    }

    @Override
    public void delDeviceByInfoAll(String imei) throws Exception {
        //报警信息
        alarmHisService.deleteByImei(imei);
        alarmHisEnService.deleteByImei(imei);
        //健康数据
        aqiHisService.deleteByImei(imei);
        bloodOxygenHisService.deleteByImei(imei);
        elevationHisService.deleteByImei(imei);
        gpsHisService.deleteByImei(imei);
        humidityHisService.deleteByImei(imei);
        outsideTemperatureHisService.deleteByImei(imei);
        pressureHisService.deleteByImei(imei);
        temperatureHisService.deleteByImei(imei);
        //sos
        sosService.deleteByImei(imei);
        //轨迹坐标
        locusCoordinateService.deleteByImei(imei);
        //设备分组
        groupDeviceService.deleteByImei(imei);
        //围栏
        FenceDevice fenceDevice = new FenceDevice();
        fenceDevice.setImei(imei);
        List<FenceDevice> fenceDeviceList = fenceDeviceService.findByAll(fenceDevice);  //查询该设备的围栏ID去删除围栏信息
        if (CollectionUtils.isNotEmpty(fenceDeviceList)) {
            //不能根据userid去删除，一个用户可能有多个设备，不同设备都设置了围栏，只能在关联表中查出对应的围栏信息进行删除
            fenceDeviceList.stream().forEach(fenceDev -> {
                fenceService.deleteByPrimaryKey(fenceDev.getFenceId());
            });
        }
        fenceDeviceService.deleteSelective(fenceDevice);
        //分配流程
        DeviceProcess deviceProcess = new DeviceProcess();
        deviceProcess.setImei(imei);
        deviceProcessService.deleteDeviceProcessSelective(deviceProcess);
        //分享
        DeviceShare deviceShare = new DeviceShare();
        deviceShare.setImei(imei);
        deviceShareService.deleteDeviceShareSelective(deviceShare);
    }

//    @Override
//    public void addNBDevice(Long userId, DeviceVO reqVO, String userName, String language) throws Exception {
//        SystemParam systemParam = null;
//        DeviceDTO query = new DeviceDTO();
//        query.setImei(reqVO.getImei());
//        int count = findCountByAll(query);
//        if (count > 0) {
//            systemParam = systemParamByCacheService.getValues(DeviceConstant.DEVICE_ENUM, DeviceConstant.DEVICE_CANT_ANAGIN_IMEI_PREFIX + language);
//            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
//        }
//        Device device = new Device();
//        device.setImei(reqVO.getImei());
//
//        CreateNbDeviceDTO createNbDeviceDTO = deviceCategoryService.queryNbParam(reqVO.getDeviceCategoryId());
//        String nbDeviceId = null;
//        // NB设备
//
//        if (createNbDeviceDTO == null) {
//            systemParam = systemParamByCacheService.getValues(DeviceConstant.DEVICE_ENUM, DeviceConstant.DEVICE_NO_DEVICE_CATEGORY_ID_PREFIX + language);
//            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
//        }
//        Integer proType = createNbDeviceDTO.getProType();
//
//
//        if (proType == null) {
//            systemParam = systemParamByCacheService.getValues(ProductConstant.PRODUCT_ENUM, ProductConstant.PRO_NO_NB_PRODUCT_ID_PREFIX + language);
//            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
//        }
//
//        if (proType.equals(1)) {
//            log.info("proType值为：1");
//            String name = createNbDeviceDTO.getName();
//            String masterKey = createNbDeviceDTO.getMasterKey();
//            if (!OptionalBean.ofNullable(name).isPresent()) {
//                systemParam = systemParamByCacheService.getValues(DeviceConstant.DEVICE_ENUM, DeviceConstant.DEVICE_NO_DEVNAME_PREFIX + language);
//                throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
//            }
//
//            if (!OptionalBean.ofNullable(masterKey).isPresent()) {
//                systemParam = systemParamByCacheService.getValues(ProductConstant.PRODUCT_ENUM, ProductConstant.PRO_NO_MASTER_KEY_PREFIX + language);
//                throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
//            }
//            RequestCreateDevice createNb = new RequestCreateDevice();
//            createNb.setDeviceName(name);
//            createNb.setImei(reqVO.getImei());
//            createNb.setOperator(userName);
//            createNb.setProductId(createNbDeviceDTO.getNbProductId());
//
//            RequestCreateDeviceParam param = new RequestCreateDeviceParam();
//            param.setAutoObserver(0);
//            param.setImse(reqVO.getImsi());
//            createNb.setOther(param);
//            CreateDeviceResponse response = deviceManagementService.createDevice(masterKey, createNb);
//            // 4.响应结果
//            int code = response.getStatusCode();
//            if (code != 200) {
//                throw new DefinitException(code, response.getMessage());
//            }
//            byte[] retBody = response.getBody();
//            System.out.println(retBody);
//            ResponseCreateDevice responseCreateDevice = JsonUtils.byteToJaveBean(retBody, ResponseCreateDevice.class);
//            Integer resCode = responseCreateDevice.getCode();
//            if (resCode != 0) {
//                throw new DefinitException(resCode, responseCreateDevice.getMsg());
//            }
//            CreateDeviceResult createProductResult = responseCreateDevice.getResult();
//            nbDeviceId = createProductResult.getDeviceId();
//
//            device.setClientId(device.getImei());
//            device.setImei(device.getImei());
//            // 状态 0 离线 1 在线 2 未激活
//            device.setState(2);
//            device.setCreateTime(new Date());
//            device.setCreatedBy(userName);
//
//        }
//
//        device.setNbDeviceId(nbDeviceId);
//        device.setIccid(reqVO.getIccid());
//        device.setImsi(reqVO.getImsi());
//        device.setName(createNbDeviceDTO.getName());
//        //应产品和测试要求超级列表添加设备时不显示公司，分配后才显示
//        /*device.setCompany(tenant.getTenantName());*/
//        device.setSysVersion(reqVO.getSysVersion());
//        device.setAppVersion(reqVO.getAppVersion());
//        device.setUserId(userId);
//        device.setOperator(reqVO.getOperator());
//        device.setSku(reqVO.getSku());
//        device.setState(2);
//        device.setCreateTime(new Date());
//        device.setCreatedBy(userName);
//        device.setUpdateTime(new Date());
//        device.setUpdatedBy(userName);
//        device.setDeviceCategoryId(reqVO.getDeviceCategoryId());
//        device.setUsed(1);
//        device.setProductId(reqVO.getProductId());
//        device.setLocation(reqVO.getLocation());
//        insertSelective(device);
//    }

    @Override
    public void unbindDevice(String imei, String language) throws Exception {
        SystemParam systemParam = null;

        //分配表
        //根据imei和解绑人（当前登录）的userId、状态为已绑定查询信息做操作：
        //1、获取分配人（上级）的id -》 更改device表的userId，并且状态为已解绑
        //2、删除分配表该设备的绑定流程
        DeviceProcess deviceProcess = new DeviceProcess();
        //deviceProcess.setReceiveId(userId);
        deviceProcess.setImei(imei);
        deviceProcess.setUsed(3);
        List<DeviceProcess> deviceProcessList = deviceProcessService.findByAll(deviceProcess);
        if (CollectionUtils.isEmpty(deviceProcessList)) {
            systemParam = systemParamByCacheService.getValues(DeviceConstant.DEVICE_ENUM, DeviceConstant.DEVICE_UNBINDING_ERROR_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }

        //分享表
        DeviceShare deviceShare = new DeviceShare();
        deviceShare.setImei(imei);
        deviceShareService.deleteDeviceShareSelective(deviceShare);

        //围栏
        FenceDevice fenceDevice = new FenceDevice();
        fenceDevice.setImei(imei);
        List<FenceDevice> fenceDeviceList = fenceDeviceService.findByAll(fenceDevice);  //查询该设备的围栏ID去删除围栏信息
        if (CollectionUtils.isNotEmpty(fenceDeviceList)) {
            //不能根据userid去删除，一个用户可能有多个设备，不同设备都设置了围栏，只能在关联表中查出对应的围栏信息进行删除
            fenceDeviceList.stream().forEach(fenceDev -> {
                fenceService.deleteByPrimaryKey(fenceDev.getFenceId());
            });
        }
        fenceDeviceService.deleteSelective(fenceDevice);

        //上级的userId
        Long operatorId = deviceProcessList.get(0).getOperatorId();

        Device device = new Device();
        device.setUserId(operatorId);   //更改为上级的id
        device.setImei(imei);
        device.setUsed(4);
        updateByImeiSelective(device);
        deviceProcessService.deleteDeviceProcessSelective(deviceProcess);
    }
}



